#include <iostream>
#include <string>
#include <errno.h>
#include <netinet/in.h>
#include <unistd.h>
// inet_pton函数所需头文件
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define MAXLINE 4096

using namespace std;

int main(int argc, char **argv)
{
    int connfd, n;
    char recvline[4096], sendline[4096];
    struct sockaddr_in servaddr;
    if (argc != 2)
    {
        cout << "usage: ./client <ipaddress>" << endl;
        return 0;
    }
    // 客户端创建socket
    if ((connfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        cout << "create socket error:" << strerror(errno) << "(errno:" << errno << ")" << endl;
        return 0;
    }
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(6666);
    // inet_pton函数将转换字符串到网络地址，第一个参数af转换后存在第三个参数中
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
    {
        cout << "inet_pton error for " << argv[1] << endl;
        return 0;
    }
    // 根据服务器ip地址和端口号试图连接服务器socket，建立与TCP服务器的连接
    // connect参数：(客户端的socket描述字，服务器的socket地址，socket地址的长度)
    if (connect(connfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
    {
        cout << "connect error:" << strerror(errno) << "(errno:" << errno << ")" << endl;
        return 0;
    }

    // 超时模块
    struct timeval stTimeValStruct;
    // 设置发送的超时时间和接收的超时时间为2s
    stTimeValStruct.tv_sec = 2;
    stTimeValStruct.tv_usec = 0;
    // 设置发送一个包超过2s就会断开连接
    if (setsockopt(connfd, SOL_SOCKET, SO_SNDTIMEO, &stTimeValStruct, sizeof(stTimeValStruct)))
    {
        cout << "setsockopt error: " << strerror(errno) << "(errno:" << errno << ")" << endl;
        return 0;
    }
    // 设置接收一个包超过2s就会断开连接
    if (setsockopt(connfd, SOL_SOCKET, SO_RCVTIMEO, &stTimeValStruct, sizeof(stTimeValStruct)))
    {
        cout << "setsockopt error: " << strerror(errno) << "(errno:" << errno << ")" << endl;
        return 0;
    }
    
    // 往服务器发送012345678的字符串
    ssize_t writenLen;
    char sendMsg[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '\0'};
    int count = 0;
    writenLen = write(connfd, sendMsg, sizeof(sendMsg));
    if (writenLen < 0)
    {
        cout << "write error: " << strerror(errno) << "(errno:" << errno << ")" << endl;
        close(connfd);
        return 0;
    }
    else
    {
        cout << "write sucess, writelen : " << writenLen << ", sendMsg: " << sendMsg << endl;
    }

    // 接收来自服务器的回包
    char readMsg[10] = {0};
    int readlen = read(connfd, readMsg, sizeof(readMsg));
    if (readlen < 0)
    {
        cout << "read error: " << strerror(errno) << "(errno:" << errno << ")" << endl;
        close(connfd);
        return 0;
    }
    else
    {
        readMsg[9] = '\0';
        cout << "read sucess, readlen : " << readlen << ", readMsg: " << readMsg << endl;
    }
    close(connfd);
    return 0;
}
